// Reflect:反射的意思，将一些Object的操作转移到Reflect对象上，使操作更合理。
// Reflect优点1：更明确的返回值：Reflect 方法通常返回一个布尔值，表示操作是否成功。这使得代码更加清晰和易于理解。
// 优点2:面向对象操作的统一性：Reflect 方法提供了一致的接口，用于执行对象的面向对象操作，如对象属性的读取、赋值、删除等。这使得我们更方便地使用这些方法。


let car={
   name:"奔驰",
   color:"红色",
   dazhe:"打折",
   door:"4",
   age:4,
   date:"2024-2-28",
   run(km){
    console.log("跑"+km)
   }
}
let arr=["pulolbg","cf","lol"];
// 1. Reflect.get("对象","属性") 查找并返回target对象的name属性值
console.log(Reflect.get(car,'color'))
console.log(Reflect.get(arr,1))
// 2. Reflect.set(obj,key,value) 在一个对象上设置属性
Reflect.set(car,"price",100)
console.log(car)
Reflect.set(arr,3,"永劫无间")
console.log(arr)
//3.Reflect.has(目标对象,key) 查找target对象的name属性是否存在,与in操作符相同
//  返回布尔值
if(Reflect.has(car,"dazhe")){
document.write(Reflect.get(car,"price")*0.8)
}else{
  document.write(Reflect.get(car,"price"))
}
// 数组中是否包含某一个数据
    console.log(arr.includes('lol'))
    console.log(arr.indexOf('kkk'))//2 返回的第一次出现的下标 未找到返回-1
// 4. Reflect.deleteProperty()  等同于delete obj[name]，用于删除对象的属性.  返回布尔值
// delete car['date']
// typeof "sdfsdf"
// car instanceof Object

let prop=Reflect.deleteProperty(car,'door');
console.log(prop,"----------------") //true
console.log(car)

// 5.(×) Reflect.construct(构造函数名称, 参数集合) 等同于new 一个对象 
// construct 构造器
function  Person(name,age) {
  this.name=name;
  this.age=age;
  this.say=function say() {
  }
}
let liudehua=new Person("刘德华",62);
let wuyifan=Reflect.construct(Person,["吴亦凡",50])
let liyifeng=Reflect.construct(Person,["李易峰",30])
console.log(wuyifan)

// 检测数据类型的方法
// typeof  检测基本数据类型
// instanceof 适合检测引用数据类型
// Object.prototype.toString.call() //最准确检测数据类型的方法
// constructor  数据的构造器是不是某一个

let a=1;
console.log(car instanceof Object,"------")
console.log(a.constructor ===Number,"-----")
let list=["李哲","麦克阿瑟","华盛顿"];
console.log(Object.prototype.toString.call(list))
console.log(Object.prototype.toString.call(car))
console.log(Object.prototype.toString.call(a))
console.log(Object.prototype.toString.call(null))
if(Object.prototype.toString.call(list)=='[object Array]'){
  console.log("数据类型是数组")
}
//6. Reflect.apply(调用的目标函数,"设置函数内的this指向",[参数集合])
// 通过指定的参数列表发起对目标(func)函数的调用     
let obj={
  name:"凤凰传奇",
  sing(adv,song){
    console.log(this.name+adv+"在唱歌"+song)
  }
}
let obj1={
  name:"周杰伦"
}

Reflect.apply(obj.sing,obj,["大声的","最炫民族风"])
Reflect.apply(obj.sing,obj1,["深情的","七里香"]);


let obj3={
  name:"周笔畅",
  say(){
    obj4.say.apply(obj3,["你好"])
  }
}
let obj4={
  name:"赵丽颖",
  say(n){
    console.log(this.name+"说话"+n)
  }
}
  
// 7.Reflect.defineProperty(目标对象,key,value||object) 
// 用来监听对象的操作
let cat={
  name:"汤姆",
  age:80,
  num:1
}
Reflect.defineProperty(cat,"age",{
  value:70,
  configurable:false,//是否能被删除
  enumerable:false,//能否被遍历
})
Reflect.defineProperty(cat,"name",{
  writable:false//能否被改写
})
Reflect.deleteProperty(cat,"age");
for(let key in cat){
  console.log(cat[key])
}
cat.name="杰瑞";
console.log(cat)
Reflect.defineProperty(cat,"num",{
  get(){
    return "新的值"
  },
  set(newVal){
    console.log(newVal)
  }
})
cat.num=88;
console.log(cat)

// 8，Reflect.ownKeys(目标对象) 返回对象的所有属性，基本等同于 Object.keys 如果是构造函数创建的对象不能获取到原型上的属性
// let myobj={
//   name:"揽胜",
//   color:"黑色",
//   price:"170w"
// }
function Student(name,age) {
    this.name=name;
    this.age=age;
}
Student.prototype.sex="男";
Student.prototype.shengao="180";
let xiaoming=new Student("小明","18")

// ["name","color","price"]
// Object.keys(对象).length==0 判断对象是否为空
console.log(Object.keys(xiaoming))
console.log(Reflect.ownKeys(xiaoming))
console.log(Object.getOwnPropertyNames(xiaoming))
let arr2=[]
for(var key in xiaoming){
  console.log(key)
  arr2.push(key)
}
console.log(arr2)

